package control;

import java.io.IOException;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import remote.AutenticazioneRemote;
import remote.GestioneAbilitaRemote;
import util.LoginToken;
import util.LoginToken.TipoAccesso;
import entity.Abilita;
import exception.LoginException;
import exception.SicurezzaException;

public class AutenticazioneServlet extends Servlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException, ServletException {
		String to = (String) request.getParameter("to");
		if (to.equals("logout"))
			this.logout(request, response);
		if (to.equals("login"))
			this.login(request, response);
	}

	// per questioni di sicurezza introduciamo 2 controlli per le 2 categorie di
	// utenti
	public static boolean checkLoggatoComeUtente(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();
		LoginToken tok = (LoginToken) session.getAttribute("LoginToken");
		if (tok == null || tok.getRequiredAccess() != TipoAccesso.Utente) { // se
																			// non
																			// sei
																			// loggato
																			// come
																			// utente
			session.setAttribute("Errore", (new SicurezzaException(
					"VIOLAZIONE DELLA SICUREZZA! Non sei loggato come utente"))
					.toString());
			redirect("index.jsp", request, response);
			return false;
		}
		return true;
	}

	public static boolean checkLoggatoComeAmministratore(
			HttpServletRequest request, HttpServletResponse response) {
		HttpSession session = request.getSession();
		LoginToken tok = (LoginToken) session.getAttribute("LoginToken");
		if (tok == null
				|| tok.getRequiredAccess() != TipoAccesso.Amministratore) { // se
																			// non
																			// sei
																			// loggato
																			// come
																			// amministratore
			session.setAttribute(
					"Errore",
					(new SicurezzaException(
							"VIOLAZIONE DELLA SICUREZZA! Non sei loggato come amministratore"))
							.toString());
			redirect("index.jsp", request, response);
			return false;
		}
		return true;
	}

	private void login(HttpServletRequest request, HttpServletResponse response) {
		HttpSession session = request.getSession();
		try {
			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("Autenticazione/remote");
			AutenticazioneRemote autenticazioneRemote = (AutenticazioneRemote) PortableRemoteObject
					.narrow(ref1, AutenticazioneRemote.class);

			String username = request.getParameter("username");
			String password = request.getParameter("password");

			LoginToken tok = autenticazioneRemote.autenticazione(username,
					password);
			session.removeAttribute("LoginToken");
			session.setAttribute("LoginToken", tok);

			if (tok.getRequiredAccess() == TipoAccesso.Amministratore)
				this.accessoAmministratore(request, response);
			if (tok.getRequiredAccess() == TipoAccesso.Utente)
				this.accessoUtente(request, response);
		} catch (LoginException e) {
			session.setAttribute("Errore", e.toString());
			redirect("index.jsp", request, response);
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}

	private void logout(HttpServletRequest request, HttpServletResponse response) {
		HttpSession session = request.getSession();
		session.removeAttribute("LoginToken");
		redirect("index.jsp", request, response);
	}

	private void accessoUtente(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();
		try {
			Context jndiContext = new javax.naming.InitialContext();

			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			LoginToken tok = (LoginToken) session.getAttribute("LoginToken");
			String username = tok.getUsername();

			session.removeAttribute("LoginToken");
			session.setAttribute("LoginToken", tok);

			List<Abilita> listaAbilita = gestioneAbilitaRemote
					.getListaAbilitaDiUtente(username);
			session.setAttribute("listaAbilita", listaAbilita);

			if (listaAbilita == null) {
				redirect("utente/listaAbilita.jsp", request, response);
			} else {
				redirect("utente/profilo.jsp", request, response);
			}
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}

	private void accessoAmministratore(HttpServletRequest request,
			HttpServletResponse response) {
		HttpSession session = request.getSession();
		try {
			Context jndiContext = new javax.naming.InitialContext();
			Object ref1 = jndiContext.lookup("GestioneAbilita/remote");
			GestioneAbilitaRemote gestioneAbilitaRemote = (GestioneAbilitaRemote) PortableRemoteObject
					.narrow(ref1, GestioneAbilitaRemote.class);

			List<Abilita> listaAbilita = gestioneAbilitaRemote
					.getListaAbilita();
			session.setAttribute("listaAbilita", listaAbilita);

			redirect("admin/listaAbilitaAdmin.jsp", request, response);
		} catch (NamingException e) {
			e.printStackTrace();
		}
	}

}
